package com.dmp.storm.bolt.dynamicdb;

import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.*;

public abstract class BaseDyInsertBatchDBBolt extends DyMapCacheBolt {
    /**
     *
     */
    private static final long serialVersionUID = -4775111753927913851L;
    private Connection connection;
    private String propPath;
    private String url;
    private String user;
    private String pwd;
    private static Map<String,String> tableMap = new HashMap<String, String>();
    
    protected String tableName;
    protected String createTableSql;
    protected String keys;
    protected String outputKeys;
    protected String extraKeys;

    @Override
    public void prepare() {
        super.prepare();
        if (propPath == null || propPath.isEmpty()) {
            propPath = "prop.properties";
        }
        Properties props = new Properties();
        try {
            props.load(this.getClass().getClassLoader().getResourceAsStream(propPath));
            url = props.getProperty("dburl");
            user = props.getProperty("dbuser");
            pwd = props.getProperty("dbpwd");
            
            String tmp = props.getProperty("timeOut");
            if(tmp != null){
            	this.setTimeOut(Integer.valueOf( tmp).intValue());
            }
            tmp = props.getProperty("recordSize");
            if(tmp != null){
            	this.setRecordSize(Integer.valueOf( tmp).intValue());
            }
            
        } catch (NullPointerException e) {
            try {
                e.printStackTrace();
                System.exit(-1);
            } catch (Exception e1) {
                e1.printStackTrace();
                System.exit(-1);
            }
        } catch (IOException e) {
            try {
                e.printStackTrace();
                System.exit(-1);
            } catch (Exception e1) {
                e1.printStackTrace();
                System.exit(-1);
            }
        } 
    }

    @Override
    public void processBatch(List<Map<String, Object>> list) {
        Statement stmt = null;
        try {
        	List<Map<String, Object>> listCp = new ArrayList<Map<String,Object>>(list);
        	Class.forName("com.mysql.jdbc.Driver");
            connection = DriverManager.getConnection(url, user, pwd);
            stmt = connection.createStatement();
            String sqlTableName = tableName + this.getNowDay();
            this.createTable(sqlTableName, stmt);
            for (Map<String, Object> map : listCp) {
                String sql = createSQLByMap(sqlTableName, keys, outputKeys, extraKeys, map);
                stmt.addBatch(sql);
            }
            stmt.executeBatch();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (stmt != null) {
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        // 暂时无返回值
    }

    public void createTable(String tableName, Statement stmt) throws SQLException{
    	if(null == tableMap.get(tableName)){
    		tableMap.put(tableName, "1");
    		String sql = " CREATE TABLE IF NOT EXISTS " + tableName + this.createTableSql;
    		stmt.execute(sql);
    	}
    }
    
    
    /**
     * @param tableName
     * @param keys
     * @param outputKeys
     * @param map
     * @return
     * @Title: createSQLByMap
     * @Description: 拼接成sql语句
     * @author suzg
     * @date 2015年10月23日 下午3:57:55
     */
    public String createSQLByMap(String tableName, String keys, String outputKeys, String extraKeys,
                                 Map<String, Object> map) throws Exception {
        StringBuilder sb = new StringBuilder();
        String[] keysArray = outputKeys.split(",");
        sb.append("INSERT INTO ").append(tableName).append(" (").append(keys).append(") VALUES(");
        // 组装map中的参数
        for (String key : keysArray) {
            String tempArray[] = key.split("=");// 判断类型
            String realKey = tempArray[0].trim();
            Object obj = map.get(realKey);
            // 处理每一个outputKeys，
            sb = everyKeyJoinToSB(sb, tempArray, obj);
        }

        sb = dealExtraKeys(sb, extraKeys, map);

        // 去掉末尾的逗号“，”
        sb = new StringBuilder(sb.toString().substring(0, sb.toString().length() - 1));
        sb.append(")");
        return sb.toString();
    }

    /**
     * @param sb
     * @param tempArray
     * @param obj
     * @return
     * @Title: everyKeyJoinToSB
     * @Description: 处理每一个outputKeys，以后不同的类型处理时，只要扩展case，处理就可以
     * @author suzg
     * @date 2015年10月26日 下午2:12:56
     */
    private StringBuilder everyKeyJoinToSB(StringBuilder sb, String[] tempArray, Object obj) {
        if (tempArray.length == 1) {
            // 默认是字符串
            sb.append("\'");
            sb.append(obj == null ? null : obj.toString());
            sb.append("\'").append(",");
        } else {
            String type = tempArray[1].trim();// 获取数据类型
            switch (type) {
                case "0":
                    sb.append("\'");
                    // 字符串
                    sb.append(obj == null ? null : obj.toString());
                    sb.append("\'").append(",");
                    break;
                case "1":
                    sb.append("\'");
                    // number
                    sb.append(obj == null ? null : obj.toString());
                    sb.append("\'").append(",");
                    break;

                default:
                    sb.append("\'");
                    sb.append(obj == null ? null : obj.toString());
                    sb.append("\'").append(",");
            }
        }

        return sb;
    }

    /**
     * @param sb
     * @param extraKeys
     * @param map
     * @return
     * @Title: dealExtraKeys
     * @Description: 处理额外需要处理的字段，具体实现需要在子类中实现
     * @author suzg
     * @date 2015年10月26日 上午11:44:55
     */
    protected abstract StringBuilder dealExtraKeys(StringBuilder sb, String extraKeys, Map<String, Object> map);

    public void setTableName(String tableName) {
        this.tableName = tableName;
    }

    public void setKeys(String keys) {
        this.keys = keys;
    }

    public void setOutputKeys(String outputKeys) {
        this.outputKeys = outputKeys;
    }

    public void setExtraKeys(String extraKeys) {
        this.extraKeys = extraKeys;
    }

	public void setPropPath(String proPath) {
		this.propPath = proPath;
	}

	public String getCreateTableSql() {
		return createTableSql;
	}

	public void setCreateTableSql(String createTableSql) {
		this.createTableSql = createTableSql;
	}

}
